package com.mt.mtbusinessmanagementsystem.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mt.mtbusinessmanagementsystem.constant.*;
import com.mt.mtbusinessmanagementsystem.mapper.GeneralMapper;
import com.mt.mtbusinessmanagementsystem.pojo.dto.CustomerDTO;
import com.mt.mtbusinessmanagementsystem.pojo.dto.DeptDTO;
import com.mt.mtbusinessmanagementsystem.pojo.dto.EmployeeDTO;
import com.mt.mtbusinessmanagementsystem.pojo.dto.LoginDTO;
import com.mt.mtbusinessmanagementsystem.pojo.entity.*;
import com.mt.mtbusinessmanagementsystem.pojo.properties.JWTProperties;
import com.mt.mtbusinessmanagementsystem.service.GeneralService;
import com.mt.mtbusinessmanagementsystem.utils.IsTrue;
import com.mt.mtbusinessmanagementsystem.utils.JwtUtils;
import com.mt.mtbusinessmanagementsystem.utils.entry.Entry;
import com.mt.mtbusinessmanagementsystem.utils.oss.OSSUtil;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class GeneralServiceImpl implements GeneralService {
    @Autowired
    private GeneralMapper generalMapper;
    @Autowired
    private JWTProperties jwtProperties;
    @Override
    public IsTrue<LoginDTO> login(Employee employee) {
        IsTrue<LoginDTO> isTrue=new IsTrue<>(true);
        //1.先获取工号对应的员工信息
        LoginDTO loginDTO=generalMapper.login(employee);
        //2.判断员工账号和密码是否对应,不符合则直接返回错误信息
        if (loginDTO==null){
            isTrue.setIsTrue(false);
            return isTrue;
        }
        //3.更新最后的登录时间
        generalMapper.updateEmployeeInfo(Employee.builder().employeeId(loginDTO.getEmployeeId()).lastLoginTime(LocalDateTime.now()).build());
        //generalMapper.updateEmployeeLastDateTime(loginDTO.getEmployeeId(), LocalDateTime.now());
        //4.创建对应的token
        Map<String,Object> client=new HashMap<>();
        client.put(JWTConstant.EMPLOYEE_ID,loginDTO.getEmployeeId());
        client.put(JWTConstant.ACCOUNT,loginDTO.getAccount());
        client.put(JWTConstant.PASSWORD,loginDTO.getPassword());
        String token= JwtUtils.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtl(), client,jwtProperties.getIssUer());
        //5.返回对应的数据
        loginDTO.setToken(token);
        isTrue.setData(loginDTO);
        return isTrue;
    }

    @Override
    public IsTrue<String> addDept(Dept dept) {
        IsTrue<String> isTrue= IsTrue.<String>builder().isTrue(true).build();
        //1.首先判断有没有这个部门名
        Integer count=generalMapper.isExistDept(dept);
        //1.1 如果有该部门名,直接返回错误信息
        if (count.equals(GeneralConstant.EXIST_NUMBER)){
            isTrue.setIsTrue(false);
            isTrue.setStr(MessageConstant.DEPT_EXIST_ERROR);
            return isTrue;
        }
        //2.向部门表插入一条数据
        generalMapper.insertDept(dept);
        Integer postID = getPostID(PostConstant.SUPERVISOR_EMPLOYEES);
        //3.修改该名员工为主管
        if (dept.getEmployeeId()!=null) {
            Employee employee = Employee.builder().employeeId(dept.getEmployeeId()).postsId(postID).deptId(getDeptID(dept.getDeptName())).build();
            generalMapper.updateEmployeeInfo(employee);
        }
        return isTrue;
    }

    @Override
    public IsTrue<String> delDept(Integer deptId) {
        //1. 判断该部门是否存在
        Integer existDept = generalMapper.isExistDept(Dept.builder().deptId(deptId).build());
        if (!existDept.equals(GeneralConstant.EXIST_NUMBER)){
            return IsTrue.<String>builder().isTrue(false).str(MessageConstant.DEPT_NOT_EXIST_ERROR).build();
        }
        //2. 将部门的员工转移到未分配
        //2.1 先查询未分配部门
        Integer notAssignedDept=getDeptID(GeneralConstant.NOT_ASSIGNED_DEPT);
        //2.2 将原先主管的职位恢复成普通员工
        Employee employee = getEmployee(Employee.builder().deptId(deptId).postsId(getPostID(PostConstant.SUPERVISOR_EMPLOYEES)).build());
        if (employee!=null) {
            generalMapper.updateEmployeeInfo(Employee.builder().employeeId(employee.getEmployeeId()).postsId(getPostID(PostConstant.ORDINARY_EMPLOYEES)).build());
        }
        //2.3 在转移员工
        generalMapper.updateEmployeeDeteId(deptId,notAssignedDept);
        //3. 删除该部门
        generalMapper.delDept(deptId);
        return IsTrue.<String>builder().isTrue(true).build();
    }

    @Override
    public Dept updateDept(Dept dept) {
        // 1.首先先判断dept字段是否携带了员工ID,携带了则先获取原来的主管信息
        boolean flag=false;         //用于后续判断是否修改员工信息的字段
        Dept oldDeptInfo = null;
        if (dept.getEmployeeId()!=null){
            flag=true;
            oldDeptInfo = getDept(dept.getDeptName());
        }
        // 2.修改部门信息
        generalMapper.updateDeptInfo(dept);
        // 3.修改原先员工的信息
        if (flag && oldDeptInfo!=null){
            generalMapper.updateEmployeeInfo(Employee.builder().employeeId(oldDeptInfo.getEmployeeId()).deptId(getDeptID(dept.getDeptName())).postsId(getPostID(PostConstant.ORDINARY_EMPLOYEES)).build());
        }
        // 4.修改现在的员工信息
        if (flag){
            generalMapper.updateEmployeeInfo(Employee.builder().employeeId(dept.getEmployeeId()).deptId(getDeptID(dept.getDeptName())).postsId(getPostID(PostConstant.SUPERVISOR_EMPLOYEES)).build());
        }
        // 5.返回数据
        return getDept(dept.getDeptName());
    }

    @Override
    public PageInfo<DeptDTO> deptInfoByList(Integer pageNumber, Integer pageSize) {
        //1.根据接收到的信息进行分页
        PageHelper.startPage(pageNumber.intValue(),pageSize.intValue());
        ArrayList<DeptDTO> list=generalMapper.deptInfoByList();
        //2.返回数据
        return new PageInfo<>(list);
    }

    @Override
    public ArrayList<Employee> employeeByDept(Integer deptId) {
        return generalMapper.employeeByDept(deptId);
    }

    @Override
    public IsTrue<String> addEmployee(EmployeeDTO employeeDTO) {
        //1.首先查询职位, 职位存在则返回职位号，不存在则添加职位，并重新查询
        Integer postID = getPostID(employeeDTO.getPostsName());
        if (postID==null){
            generalMapper.insertPost(employeeDTO.getPostsName());
            postID=getPostID(employeeDTO.getPostsName());
        }
        employeeDTO.setPostsId(postID);
        //2.查询工号是否一致,如果一致则进行修改
        Employee employee = getEmployee(Employee.builder().employeeId(employeeDTO.getEmployeeId()).build());
        //2.1 不一致则返回错误信息
        if (employee!=null){
            return IsTrue.<String>builder().isTrue(false).str(MessageConstant.EMPLOYEE_ID_IS_THE_SAME_ERROR).build();
        }
        //3.向员工表插入一条数据
        generalMapper.addEmployee(employeeDTO);
        //4.返回结果
        return IsTrue.<String>builder().isTrue(true).build();
    }

    @Override
    public void putEmployee(Employee employee) {
        //1.根据employeeID修改信息
        generalMapper.updateEmployeeInfo(employee);
    }

    @Override
    public String putEmployeeHead(String employeeId, MultipartFile headFile) {
        //1.首先先上传头像并返回头像的url地址
        String url = OSSUtil.uploadFled(headFile, OSSConstant.EMPLOYEE_HEAD_DIRECTORY);
        //2.根据返回的url地址修改员工信息
        generalMapper.updateEmployeeInfo(Employee.builder().employeeId(employeeId).imageUrl(url).build());
        //3.返回数据
        return url;
    }

    @Override
    public PageInfo<EmployeeDTO> queryEmployeeList(EmployeeDTO employeeDTO) {
        //1. 判断传输过来的是否是部门名，是的话则重置为部门ID
        if (employeeDTO.getPostsName()!=null){
            employeeDTO.setPostsId(getPostID(employeeDTO.getPostsName()));
        }
        //2.分页查询员工列表
        PageHelper.startPage(employeeDTO.getPageNumber().intValue(),employeeDTO.getPageSize().intValue());
        ArrayList<EmployeeDTO> list=generalMapper.queryEmployeeList(employeeDTO);
        //3.返回数据
        return new PageInfo<>(list);
    }

    @Override
    @Transactional
    public IsTrue<CustomerDTO> addCustomer(CustomerDTO customerDTO) {
        //0. 判断customerID是否为空,为空返回错误信息，不为空则进行下一步
        if (customerDTO.getCustomerId()==null){
            return IsTrue.<CustomerDTO>builder().isTrue(false).str(String.format(MessageConstant.DATA_IS_NULL, GeneralConstant.CUSTOMER_ID)).build();
        }

        try {
            //1. 先查看是否有传输公司名,有的话查询是否有该家公司,没有的话进行下一步
            //1.1有的话直接返回公司号ID
            if (customerDTO.getCompanyName()!=null) {
                Company company = getCompany(customerDTO.getCompanyName());
                //1.2没有的话直接插入一条数据，再查询公司号ID
                if (company == null) {
                    generalMapper.addCompany(customerDTO);
                    company = getCompany(customerDTO.getCompanyName());
                }
                customerDTO.setCompanyId(company.getCompanyId());
            }
            //2. 向客户表插入一条数据
            //2.1更新部分数据
            customerDTO.setCreateDate(LocalDateTime.now());
            customerDTO.setUpdateDate(LocalDateTime.now());
            //2.2向客户表插入数据
            generalMapper.addCustomer(customerDTO);
            //3.向跟进表插入一条数据
            generalMapper.addFollow(Follow.builder().customerId(customerDTO.getCustomerId())
                    .employeeId(customerDTO.getEmployeeId()).startDate(LocalDateTime.now()).build());
            //4. 返回一条数据
            return IsTrue.<CustomerDTO>builder().isTrue(true).data(customerDTO).build();
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return IsTrue.<CustomerDTO>builder().isTrue(false).str(MessageConstant.CUSTOMER_ADD_ERROR).build();
        }
    }

    @Override
    public PageInfo<CustomerDTO> queryCustomerList(CustomerDTO customerDTO) {
        //1. 先做分页设置
        PageHelper.startPage(customerDTO.getPageNumber().intValue(),customerDTO.getPageSize().intValue());
        //2. 再根据传递过来的信息进行查询
        ArrayList<CustomerDTO> list=generalMapper.queryCustomerList(customerDTO);
        //3.返回数据
        return new PageInfo<>(list);
    }

    @Override
    public Entry<Entry<String, ArrayList<CustomerDTO>>, Entry<String, ArrayList<CustomerDTO>>> queryCreateAndResponsibleInfo() {
        //1. 查询创建人信息
        ArrayList<CustomerDTO> createInfo=generalMapper.queryCreateInfo();
        //2. 查询负责人信息
        ArrayList<CustomerDTO> responsibleInfo=generalMapper.queryResponsibleInfo();
        //3. 填入数据
        Entry<Entry<String, ArrayList<CustomerDTO>>, Entry<String, ArrayList<CustomerDTO>>> entry=new Entry<>(
                new Entry<>(GeneralConstant.CREATE_INFO,createInfo),new Entry<>(GeneralConstant.RESPONSIBLE_INFO,responsibleInfo));
        //4.返回数据
        return entry;
    }

    @Override
    public ArrayList<Employee> employeeByDeptName(String deptName) {
        //1. 根据部门名查询deptID
        Integer deptId = getDeptID(deptName);
        //2. 根据deptID返回员工列表并返回数据
        return generalMapper.employeeByDept(deptId);
    }

    @Override
    @Transactional
    public void customerPut(Customer customer) {
        //1.更新时间并修改数据
        customer.setUpdateDate(LocalDateTime.now());
        generalMapper.customerPut(customer);
        //2.如果employeeID存在, 则意味着需要修改跟进表
        if (customer.getEmployeeId()!=null){
            Follow follow=getFollow(customer.getCustomerId());
            follow.setEmployeeId(customer.getEmployeeId());
            generalMapper.followPut(follow);
        }
    }

    @Override
    public IsTrue<CustomerDTO> customerDetailedInfo(CustomerDTO customerDTO) {
        //0. 查询是否传递customerId,没有则传递错误信息
        if (customerDTO.getCustomerId()==null){
            return IsTrue.<CustomerDTO>builder().isTrue(false).str(String.format(MessageConstant.DATA_IS_NULL, GeneralConstant.CREATE_INFO)).build();
        }
        //1. 根据customerId先获取部分信息
        CustomerDTO newCustomer=generalMapper.customerDetailedInfo(customerDTO);
        //2. 再根据employeeId获取employeeName获取信息
        String employeeName = getEmployee(Employee.builder().employeeId(newCustomer.getEmployeeId()).build()).getEmployeeName();
        newCustomer.setEmployeeName(employeeName);
        //3. 返回数据
        return IsTrue.<CustomerDTO>builder().isTrue(true).data(newCustomer).build();
    }

    @Override
    public IsTrue addFollowMethod(FollowMethod followMethod) {
        //1.先到数据库中查询是否有重复的信息,
        FollowMethod newFollowMethod= getFollowMethod(followMethod);
        //2.有重复信息则直接返回错误信息
        if (newFollowMethod!=null){
            return IsTrue.builder().isTrue(false).str(String.format(MessageConstant.DATA_EXIST_ERROR, GeneralConstant.FOLLOW_METHOD)).build();
        }
        //3.没有重复信息就直接向跟进方式表插入一条数据
        generalMapper.addFollowMethod(followMethod);
        //4.返回数据
        return IsTrue.builder().isTrue(true).build();
    }

    @Override
    @Transactional
    public IsTrue<String> delFollowMethod(Integer followMethodId) {
        //1. 首先先查询followMethodId是否存在
        FollowMethod followMethod = getFollowMethod(FollowMethod.builder().followMethodsId(followMethodId).build());
        //2. 不存在则代表不能删除,直接返回错误信息
        if (followMethod==null){
            return IsTrue.<String>builder().isTrue(false).str(String.format(MessageConstant.DATA_NOT_EXIST_ERROR, GeneralConstant.FOLLOW_METHOD_ID)).build();
        }
        //3. 存在则直接删除信息
        generalMapper.delFollowMethod(followMethodId);
        //4. 返回删除成功信息
        return IsTrue.<String>builder().isTrue(true).build();
    }
    //暂时不用
//    @Override
//    @Transactional
//    public IsTrue<String> delCustomer(CustomerDTO customerDTO) {
//        //1.判断传递过来的数据是否合法, 不合法返回错误信息
//        if (customerDTO.getCustomerId()==null&&customerDTO.getId()==null){
//            return IsTrue.<String>builder().isTrue(false).str(String.format(MessageConstant.DATA_IS_NULL,
//                    String.format(GeneralConstant.MERGER, GeneralConstant.CUSTOMER_ID,GeneralConstant.ID))).build();
//        }
//        //2. 如果只传递过来ID,则直接获取需要被删除的对象
//        if (customerDTO.getCustomerId()==null){
//            customerDTO=getCustomer(customerDTO.getId());
//        }
//        //3.删除数据,及其附带的数据
//        generalMapper.delCustomer(customerDTO);
//        generalMapper.getFollow(customerDTO.getCustomerId());
//
//
//
//
//        return null;
//    }
    private FollowMethod getFollowMethod(FollowMethod followMethod) {
        return generalMapper.getFollowMethod(followMethod);
    }

    private CustomerDTO getCustomer(Integer id) {
        return generalMapper.getCustomer(id);
    }


    private Follow getFollow(String customerId){
        return generalMapper.getFollow(customerId);
    }

    private Company getCompany(String companyName) {
        return generalMapper.getCompany(companyName);
    }


    private Integer getDeptID(String deptName) {
        return generalMapper.getDeptID(deptName);
    }

    private Dept getDept(String deptName) {
        return generalMapper.getDept(deptName);
    }
    private Integer getPostID(String postName){
        return generalMapper.getPostID(postName);
    }
    private Employee getEmployee(Employee employee){
        return generalMapper.getEmployee(employee);
    }

}
